package com.itany.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * Author:石小俊
 * Date: 2022/11/4 11:52
 */
public class LogInvocationHandler implements InvocationHandler {

    // 由于代理方法需要代理所有目标类中的所有方法
    // 只有在运行时才能确定代理对象
    // 因此,在获取代理对象的时候,可以将当前代理对象所代理的目标类传递进来
    // 由于调用者是通过构造方法来进行调用的,且我们必须指定代理的目标对象是谁
    // 因此,可以提供一个有参构造方法,参数即为当前所代理的目标对象
    // 不能提供无参构造方法,因为调用者必须传递目标对象

    // 定义目标对象
    private Object target;

    // 有参构造方法
    public LogInvocationHandler(Object target) {
        this.target = target;
    }

    /**
     * 代理方法
     * @param proxy     生成的代理对象,代理对象是在运行时生成,基本没用
     * @param method    代理的目标方法
     * @param args      代理的目标方法的参数列表
     * @return          目标方法的返回值
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 执行目标方法之前
        System.out.println("执行目标方法之前的动态代理,在"+new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date())+"执行了"+method.getName()+"方法,方法的参数列表为:"+ Arrays.toString(args));
        // 执行目标方法
        // 执行目标方法
        // 参数一:执行的目标方法所在的目标对象
        // 参数二:目标方法的参数列表
        // 返回值:目标方法的返回值
        Object result = method.invoke(target, args);
        System.out.println("执行目标方法之后的动态代理,"+method.getName()+"方法返回值为:"+result);
        // 执行目标方法之后
        return result;
    }
}
